package io.mft.runtime.function.combination.component;

import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.mft.api.domain.ExecuteMode;
import io.mft.commons.function.ExecuteReturn;
import io.mft.flow.core.executable.ExecutableType;
import io.mft.flow.core.executable.component.NodeComponent;
import io.mft.flow.data.ChainContext;
import io.mft.runtime.MFTApiExecutor;
import io.mft.runtime.function.ApiContext;
import io.mft.runtime.function.ApiExecutorObject;
import io.mft.runtime.function.ApiFunctionRequest;
import io.mft.runtime.function.ApiFunctionResponse;
import io.mft.runtime.function.combination.CombinationRegulationApiFunctionExecutor;
import io.mft.runtime.thread.AsyncExecuteThreadPool;
import io.mft.runtime.thread.AsyncExecuteThreadPool.AsyncWorker;

/**
 * 编排API执行处理组件
 * 
 * @说明：TODO
 * @类型名称：CombinationFunctionComponent
 * @创建者: 胡常建
 * @创建时间: 2021年2月21日 下午8:50:04
 * @修改者: 胡常建
 * @修改时间: 2021年2月21日 下午8:50:04
 */
public class CombinationApiFunctionExecutorComponent extends NodeComponent {

	Logger logger=LoggerFactory.getLogger(getClass());
	@Override
	public ExecutableType getType() {
		return ExecutableType.NODE;
	}

	@Override
	public String getId() {
		return CombinationApiFunctionExecutorComponent.class.getName();
	}

	@Override
	public ExecuteReturn execute(ChainContext context) throws Exception {
		String key=getNodeId();
		String uniqueId=context.getExecutableUniqueId();
		logger.debug("编排API执行处理组件->>>逻辑单元编排Chain:{}->>>当前规则KEY:{}->>>初始入参:{}->>>过程入参:{}",context.getChainName(),uniqueId,context.getChainInitialRequest(),context.getRequest());
		ApiExecutorObject apiExecutorObject=MFTApiExecutor.getInstance().getRuntimeResource().getApiCache().getApiExecutorObject(context.getChainName());
		
		
		CombinationRegulationApiFunctionExecutor regulationExecutor = apiExecutorObject.getRegulationExecutor(uniqueId);
		ExecuteMode executeMode=regulationExecutor.getApiRegulation().getRegulation().getExecuteMode();
		ApiExecutorObject regulationApiExecutorObject = MFTApiExecutor.getInstance().getRuntimeResource().getApiCache().getApiExecutorObject(key);
		ApiFunctionResponse apiFunctionResponse=new ApiFunctionResponse(context.getResponse());
		ApiFunctionRequest apiFunctionRequest=new ApiFunctionRequest(context.getRequest().getRequestValue());
		apiFunctionRequest.getRequestValue().set("currentRuningCombinationRegulationUniqueId",uniqueId);
		apiFunctionRequest.getRequestValue().set("currentRuningCombinationRegulationApiKey",key);
		apiFunctionRequest.getRequestValue().set("currentRuningCombinationApiKey",context.getChainName());
		
		ApiContext regulationExecutorContext = new ApiContext(regulationApiExecutorObject, apiFunctionRequest,apiFunctionResponse);
		if (executeMode==ExecuteMode.async||executeMode==ExecuteMode.syncWaitAsync) {
			try {
				Future<?> future=AsyncExecuteThreadPool.execute(regulationExecutor.getApiRegulation().getRegulation(), new AsyncWorker() {
					
					@Override
					public void work() {
						try {
							regulationExecutor.doExecute(regulationExecutorContext);
						} catch (Exception e) {
							logger.error("",e);
						}
					}
				});
				return ExecuteReturn.builder().asyncFuture(future).build();
			} catch (Exception e) {
				logger.error("",e);
			}
			return ExecuteReturn.builder().build();
		}else {
			return regulationExecutor.doExecute(regulationExecutorContext);
		}
	}
	
	
}
